<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>文档对象模型导航获取元素(Document Object Model Navigation Get Elements)</title>
  <!-- 
  在JavaScript中，文档对象模型（DOM）提供了一种结构化的方式来访问和操作HTML文档中的元素。通过DOM，开发者可以动态地获取、修改、添加和删除页面元素。
  一、DOM结构
  DOM将HTML文档表示为一个树形结构，文档的每个部分（如元素、文本和属性）都是树中的一个节点。根节点是 `document` 对象，其他节点是元素节点、文本节点等。

  二、获取元素的方法
  1. 通过ID获取元素：
    - 使用 `document.getElementById()` 方法可以根据元素的 `id` 属性获取单个元素。
    const element = document.getElementById('myElement');

  2. 通过类名获取元素：
    - 使用 `document.getElementsByClassName()` 方法可以根据元素的类名获取一个元素集合（HTMLCollection）。
    const elements = document.getElementsByClassName('myClass');
    console.log(elements[0]); // 获取第一个匹配的元素

  3. 通过标签名获取元素：
    - 使用 `document.getElementsByTagName()` 方法可以根据标签名获取一个元素集合。
    const paragraphs = document.getElementsByTagName('p');
    console.log(paragraphs.length); // 输出所有<p>元素的数量

  4. 通过选择器获取元素：
    - 使用 `document.querySelector()` 方法可以根据CSS选择器获取第一个匹配的元素。
    - 使用 `document.querySelectorAll()` 方法可以获取所有匹配的元素，返回一个NodeList。
    const firstDiv = document.querySelector('div'); // 获取第一个<div>
    const allItems = document.querySelectorAll('.item'); // 获取所有带有类名item的元素
    
  三、DOM导航
  DOM提供了一些属性和方法来导航节点之间的关系：

  1. 父节点：
    - 使用 `parentNode` 属性获取当前节点的父节点。
    const child = document.getElementById('myElement');
    const parent = child.parentNode;

  2. 子节点：
    - 使用 `childNodes` 属性获取当前节点的所有子节点（包括文本节点）。
    - 使用 `children` 属性获取当前节点的所有子元素（不包括文本节点）。
    const parent = document.getElementById('parentElement');
    const children = parent.childNodes; // 包括所有子节点
    const childElements = parent.children; // 仅包括子元素

  3. 第一个和最后一个子节点：
    - 使用 `firstChild` 和 `lastChild` 属性获取第一个和最后一个子节点。
    - 使用 `firstElementChild` 和 `lastElementChild` 获取第一个和最后一个子元素。
    const firstChild = parent.firstChild;
    const lastChild = parent.lastChild;
    const firstElement = parent.firstElementChild;
    const lastElement = parent.lastElementChild;

  4. 兄弟节点：
    - 使用 `nextSibling` 和 `previousSibling` 属性获取当前节点的下一个和上一个兄弟节点。
    - 使用 `nextElementSibling` 和 `previousElementSibling` 获取下一个和上一个兄弟元素。
    const sibling = child.nextSibling; // 获取下一个兄弟节点
    const nextElement = child.nextElementSibling; // 获取下一个兄弟元素

  四、总结
  - DOM提供了一种结构化的方式来访问和操作HTML文档中的元素。
  - 可以通过 `getElementById` 、 `getElementsByClassName` 、 `getElementsByTagName` 、 `querySelector` 和 `querySelectorAll` 等方法获取元素。
  - DOM导航可以通过父节点、子节点、兄弟节点等属性进行，方便开发者在节点树中进行操作。
   -->
</head>
<body>

  <div class="document-object-model">
    <h3>文档对象模型导航获取元素(Document Object Model Navigation Get Elements)</h3>
    <div class="container">
      <p>
        DOM将HTML文档表示为一个树形结构，文档的每个部分（如元素、文本和属性）都是树中的一个节点。
        <span class="highlight">根节点是 `document` 对象</span>，其他节点是元素节点、文本节点等。
      </p>
      <p>
        DOM将HTML文档表示为一个树形结构，文档的每个部分（如元素、文本和属性）都是树中的一个节点。
        <span class="highlight">根节点是 `document` 对象</span>，其他节点是元素节点、文本节点等。
      </p>

      <div class="article">
        <h3 id="article-title">总结</h3>
        <p>
          - DOM提供了一种结构化的方式来访问和操作HTML文档中的元素。
          - 可以通过 `getElementById` 、 `getElementsByClassName` 、 `getElementsByTagName` 、 `querySelector` 和 `querySelectorAll` 等方法获取元素。
          - DOM导航可以通过父节点、子节点、兄弟节点等属性进行，方便开发者在节点树中进行操作。
        </p>
      </div>
    </div>
  </div>

  <script>
    
    // 1. 导航获取
    // 1.1 获取根节点 body
    const bodyEl = document.body;

    // 1.2 获取根节点 html / document
    const documentEl = document.documentElement;

    // 1.3 获取 document-object-model
    const documentObjectModelEl = bodyEl.firstElementChild;

    // 1.4 获取导航获取元素 container
    const containerEl = documentObjectModelEl.children[1];

    // 1.5 获取导航获取元素 p
    const pEl = containerEl.children[0];

    // 1.6 获取导航获取元素 highlight
    const highlightEl = pEl.children[0];
    highlightEl.style.color = "red";
    console.log("导航获取", bodyEl, documentEl, documentObjectModelEl, containerEl, pEl, highlightEl);
    

    // 2. 查询获取
    // 2.1 获取导航获取元素 article
    const articleEl = document.querySelector(".article");

    // 2.2 获取导航获取元素 h3
    const h3El = articleEl.querySelector("h3");

    // 2.3 获取导航获取元素 p
    const p2El = articleEl.querySelector("p");

    // 2.4 获取导航获取元素 p
    const p3El = articleEl.querySelector(".article p");

    // 2.5 获取导航获取元素 p
    const p6El = articleEl.querySelector("p:nth-child(2)");

    // 2.6 获取导航获取元素 p
    const p7El = articleEl.querySelector("p:last-child");
    console.log("查询获取", articleEl, h3El, p2El, p3El, p6El, p7El);
    
    // 3. 获取所有元素
    // 3.1 获取导航获取元素 p
    const p10El = articleEl.querySelectorAll("p:nth-child(2)")[0];

    // 3.2 获取导航获取元素 p
    const p11El = articleEl.querySelectorAll("p:last-child")[0];

    // 3.3 获取导航获取元素 p
    const p12El = articleEl.querySelectorAll("p")[articleEl.querySelectorAll("p").length - 1];
    console.log("获取所有元素", p10El, p11El, p12El);
    
    
  </script>
  
</body>
</html>